import base64
import cv2
from typing import List
import os
import shutil
import subprocess

class VideoProcessor:
    def extract_video_frames(self, video_path: str, frame_count: int = 3) -> List[str]:
        frames = []
        cap = cv2.VideoCapture(video_path)
        if not cap.isOpened():
            return frames
        total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        interval = max(1, total_frames // max(1, frame_count))
        # configurable frame size and JPEG quality
        width = int(os.getenv('FRAME_WIDTH', '480'))
        height = int(os.getenv('FRAME_HEIGHT', '360'))
        quality = int(os.getenv('JPEG_QUALITY', '70'))
        for i in range(frame_count):
            idx = i * interval
            cap.set(cv2.CAP_PROP_POS_FRAMES, idx)
            ret, frame = cap.read()
            if not ret:
                continue
            frame = cv2.resize(frame, (width, height))
            _, buf = cv2.imencode('.jpg', frame, [int(cv2.IMWRITE_JPEG_QUALITY), quality])
            frames.append(base64.b64encode(buf).decode('utf-8'))
        cap.release()
        return frames

    def get_video_duration(self, video_path: str) -> float:
        # 优先使用 ffprobe（更可靠）
        ffprobe = shutil.which('ffprobe')
        if ffprobe:
            try:
                proc = subprocess.run(
                    [ffprobe, '-v', 'error', '-show_entries', 'format=duration', '-of',
                     'default=noprint_wrappers=1:nokey=1', video_path],
                    text=True, capture_output=True, check=False, timeout=10
                )
                if proc.returncode == 0:
                    s = proc.stdout.strip()
                    if s:
                        return float(s)
            except Exception:
                pass
        # OpenCV 兜底并限幅 fps，避免极小/异常帧率导致时长虚高
        cap = cv2.VideoCapture(video_path)
        if not cap.isOpened():
            return 0.0
        fps = cap.get(cv2.CAP_PROP_FPS) or 0.0
        total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        cap.release()
        # 合理范围：5–120，否则使用备用 fps
        if fps < 5 or fps > 120:
            fps = float(os.getenv('FALLBACK_FPS', '25'))
        return total_frames / fps if fps else 0.0

    def categorize_duration(self, duration: float) -> str:
        # 与配置 categories_example.txt 对齐：≤15秒 / ≤1分钟 / ≤5分钟 / ＞5分钟
        if duration <= 15:
            return '≤15秒'
        elif duration <= 60:
            return '≤1分钟'
        elif duration <= 5 * 60:
            return '≤5分钟'
        else:
            return '＞5分钟'
